﻿using HslCommunication.Core.Net;
using Net_SCADA.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Net_SCADA
{
    public partial class Form_Monitor : fdBaseForm
    {

        //门的位置定义
        private List<ControlPos> door = new List<ControlPos>();
        private List<ControlPos> lift = new List<ControlPos>();
        private List<ControlPos> car = new List<ControlPos>();
        private List<PictureBox> motor = new List<PictureBox>();
        private List<PictureBox> fan = new List<PictureBox>();

        private int[] motorStatusID = new int[] { 454, 455, 454, 455, 496, 497, 498, 499, 500, 501, 502, 503, 508, 509, 510 };
        private int[] fanStatusID = new int[] { 439, 440, 441, 454, 455, 454, 455, 490, 491, 496, 497, 498, 499, 500, 501, 502, 503 };
        private int[] doorStatusID = new int[] { 127, 128, 132, 133, 138, 139, 142, 143, 149, 150, 151, 152, 166, 167, 168, 169, 177, 178, 182, 183, 280, 281, 397, 398, 399, 400, 295, 296, 297, 298, 299, 300, 401, 402, 403, 404, 360, 361, 362, 363, 337, 338, 339, 340, 345, 346, 364, 365, 347, 348, 366, 367 };
        private int[] liftStatusID = new int[] { 129, 130, 209, 210, 270, 271, 275, 276, 303, 304, 405, 406, 320, 321, 322, 323, 341, 342, 368, 369 };
        private int[] car1StatusID = new int[] {286,390,391,393 };//0，1，1，2
        private int[] car2StatusID = new int[] {318,329 };//0，1
        Alarm[] car1;
        Alarm[] car2;

        //内部变量
        private Dictionary<fdCtrZone, Zone> _monitorzone = new Dictionary<fdCtrZone, Zone>();
        private System.Timers.Timer _tim = new System.Timers.Timer(1000) { AutoReset = true };
        private System.Timers.Timer _timfan = new System.Timers.Timer(1000) { AutoReset = true };
        bool isfantop = true;
        List<object> EquipStatus = new List<object>();

        private List<Label> lblBox = new List<Label>();
        private bool isShowOverPV = false;

        public Form_Monitor()
        {
            InitializeComponent();
        }

        private void Form_Moniter_Load(object sender, EventArgs e)
        {
            formLanguageIndex = -1;
            netForms.SetPostionAndSize(this);
            LoadInterface();
            initInterface();
            car1 = new Alarm[car1StatusID.Length];
            car2 = new Alarm[car2StatusID.Length];
            for (int i = 0; i < car1.Length ; i++)
            {
                car1[i] = NetLine.status.Find(x => x.AlarmID == car1StatusID[i]);
            }
            for (int i = 0; i < car2.Length; i++)
            {
                car2[i] = NetLine.status.Find(x => x.AlarmID == car2StatusID[i]);
            }
            _tim.Elapsed += _tim_Elapsed; ;
            _timfan.Elapsed += _timfan_Elapsed;
            _tim.Start();
            _timfan.Start();
        }

        private void _timfan_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            isfantop = !isfantop;
            //显示风扇的状态16,28
            try
            {
                for (int i = 0; i < fanStatusID.Length; i++)
                {
                    this.Invoke((EventHandler)delegate
                    {
                        Alarm v = NetLine.status.Find(x => x.AlarmID == fanStatusID[i]);
                        if(v!=null)
                            fan[i].Top = v.AlarmValue & isfantop ? -fan[i].Height / 2 : 0;
                    });
                }
            }
            catch (Exception)
            {
            }
        }

        private void initInterface()
        {
            door.Add(new ControlPos() { ctl = door0, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door1, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door2, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door3, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door4, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door5, upside = 97, downside = 117});

            door.Add(new ControlPos() { ctl = door6, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door7, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door8, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door9, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door10, upside = 97, downside = 117 });

            door.Add(new ControlPos() { ctl = door11, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door12, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door13, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door14, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door15, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door16, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door17, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door18, upside = 97, downside = 117 });
            door.Add(new ControlPos() { ctl = door19, upside = 97, downside = 117 });

            door.Add(new ControlPos() { ctl = door20, upside = 317, downside = 337 });
            door.Add(new ControlPos() { ctl = door21, upside = 317, downside = 337 });

            door.Add(new ControlPos() { ctl = door22, upside = 319, downside = 337 });
            door.Add(new ControlPos() { ctl = door23, upside = 319, downside = 337 });
            door.Add(new ControlPos() { ctl = door24, upside = 322, downside = 360 });
            door.Add(new ControlPos() { ctl = door25, upside = 322, downside = 360 });

           // lift.Add(new ControlPos() { ctl = pnl_lift0, upside = 353, downside = 368 });//升降台
            lift.Add(new ControlPos() { ctl = pnl_lift1, upside = 117, downside = 146 });//前碱洗升降机
            lift.Add(new ControlPos() { ctl = pnl_lift2, upside = 117, downside = 146 });//前清洗升降机

            lift.Add(new ControlPos() { ctl = pnl_lift3, upside = 117, downside = 230 });//油槽升降机1
            lift.Add(new ControlPos() { ctl = pnl_lift4, upside = 117, downside = 230 });//油槽升降机2

            lift.Add(new ControlPos() { ctl = pnl_lift5, upside = 117, downside = 146 });//后清洗升降机1
            lift.Add(new ControlPos() { ctl = pnl_lift6, upside = 117, downside = 146 });//后清洗升降机2
            lift.Add(new ControlPos() { ctl = pnl_lift7, upside = 117, downside = 146 });//冷却槽升降机1
            lift.Add(new ControlPos() { ctl = pnl_lift8, upside = 117, downside = 146 });//冷却槽升降机2

            lift.Add(new ControlPos() { ctl = pnl_lift9, upside = 333, downside = 356 });//回火升降机1
            lift.Add(new ControlPos() { ctl = pnl_lift10, upside = 333, downside = 356 });//回火升降机2

            car.Add(new ControlPos() { ctl = pnl_car1, upside = 117, downside = 170 });//前转移小车，
            car.Add(new ControlPos() { ctl = pnl_car2, upside = 294, downside = 358 });//后转移小车，

            for (int i = 0; i < 11; i++)
            {
                motor.Add(this.Controls.Find("motor" + i, true)[0] as PictureBox);
            }
            for (int i = 0; i < 13; i++)
            {
                fan.Add(this.Controls.Find("fan" + i, true)[0] as PictureBox);
            }
        }

        private void _tim_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ShowBoxStatus();
            SetZoneData();
            SetEquipStatus();
        }


        private void SetEquipStatus()
        {
            try
            {
                EquipStatus = NetLine.hsl_Status.ItemValues;//获取设备的所有状态
                if (EquipStatus.Count != NetLine.hsl_Status.hslitems.Count) return;

                //切换碳控氧控状态
                this.Invoke((EventHandler)delegate
                {
                    Alarm v1 = NetLine.status.Find(x => x.AlarmID == 686);
                    if(v1!=null)
                        fdCtrZone11.lbl_Name.BackColor = fdCtrZone31.lbl_Name.BackColor = v1.AlarmValue ? Color.Lime : Color.LightGray;
                });
                this.Invoke((EventHandler)delegate
                {
                    Alarm v1 = NetLine.status.Find(x => x.AlarmID == 687);
                    if(v1!=null)
                        fdCtrZone37.lbl_Name.BackColor = fdCtrZone32.lbl_Name.BackColor = v1.AlarmValue ? Color.Lime : Color.LightGray;
                });

                //显示马达的状态
                this.Invoke((EventHandler)delegate
                {
                    for (int i = 0; i < motor.Count; i++)
                    {
                        Alarm v = NetLine.status.Find(x => x.AlarmID == motorStatusID[i]);
                        if (v != null)
                            motor[i].Top = v.AlarmValue ? -motor[i].Height / 2:0;
                    }
                });

                //显示升降机的状态
                for (int i = 0; i < lift.Count; i++)
                {
                    this.Invoke((EventHandler)delegate
                    {
                        Alarm v1 = NetLine.status.Find(x => x.AlarmID == liftStatusID[i*2]);
                        Alarm v2 = NetLine.status.Find(x => x.AlarmID == liftStatusID[i*2+1]);
                        if (v1 != null && v2 != null)
                        {
                            if (v1.AlarmValue)
                            {
                                lift[i].ctl.Top = lift[i].upside;
                            }
                            else if (v2.AlarmValue)
                            {
                                lift[i].ctl.Top = lift[i].downside;
                            }
                            else
                                lift[i].ctl.Top = (lift[i].downside + lift[i].upside) / 2;
                        }
                    });
                }
                //显示门的状态,每个门有两个位置
                for (int i = 0; i < door.Count; i++)
                {
                    this.Invoke((EventHandler)delegate
                    {
                        Alarm v1 = NetLine.status.Find(x => x.AlarmID == doorStatusID[i * 2]);
                        Alarm v2 = NetLine.status.Find(x => x.AlarmID == doorStatusID[i * 2 + 1]);
                        if (v1 != null && v2 != null)
                        {
                            if (v1.AlarmValue)
                            {
                                door[i].ctl.Top = door[i].upside;
                                door[i].ctl.BackColor = Color.Red;
                            }
                            else if (v2.AlarmValue)
                            {
                                door[i].ctl.Top = door[i].downside;
                                door[i].ctl.BackColor = Color.LimeGreen;
                            }
                            else
                            {
                                door[i].ctl.Top = (door[i].downside + door[i].upside) / 2;
                                if (door[i].ctl.BackColor != Color.Red)
                                    door[i].ctl.BackColor = Color.Red;
                                else
                                    door[i].ctl.BackColor = Color.Yellow;
                            }
                        }
                    });
                }

                //显示车的动画 car1 99~104，car2 105~108
                //小车1（上下料端）

                this.Invoke((EventHandler)delegate
                {
                    
                    if (car1[0]!=null && car1[0].AlarmValue)
                    {
                        car[0].ctl.Top = 116;
                    }
                    else if (car1[1]!=null && car1[2]!=null && (car1[1].AlarmValue || car1[2].AlarmValue))
                    {
                        car[0].ctl.Top = 432;
                    }
                    else if (car1[3] != null && car1[3].AlarmValue)
                    {
                        car[0].ctl.Top = 379;
                    }
                    else
                    {
                        car[0].ctl.Top = 265;//中间位置
                    }
                });
                //小车2（淬火清洗后）

                this.Invoke((EventHandler)delegate
                {
                    if (car2[0]!=null && car2[0].AlarmValue)
                    {
                        car[1].ctl.Top = 117;
                    }
                    else if(car2[1] != null && car2[1].AlarmValue)
                    {
                        car[1].ctl.Top = 412;
                    }
                    else
                    {
                        car[1].ctl.Top = 265;
                    }
                });
            }
            catch (Exception)
            {
            }
        }



        private void LoadInterface()
        {
            //显示工位信息的label
            Label lbl = null;
            for (int i = 0; i < NetLine.pBox.Count; i++)
            {
                lbl = this.Controls.Find("Label" + (i + 1), true)[0] as Label;
                lbl.ForeColor = Color.Silver;
                lbl.Click += LblBox_Click;
                lbl.Tag = i;
                lbl.Text = (i + 1).ToString();
                lblBox.Add(lbl);
            }
            //显示参数的fdctrzone
            foreach (var item in this.Controls)
            {
                SetfdCtrZoneTitle(item);
            }
            foreach (var item in pnl_Body.Controls)
            {
                SetfdCtrZoneTitle(item);
            }
            //碳势，氧势颜色现实
            fdCtrZone11.lbl_Name.ForeColor = fdCtrZone31.lbl_Name.ForeColor = fdCtrZone32.lbl_Name.ForeColor = fdCtrZone37.lbl_Name.ForeColor = Color.Black;
        }

        private void SetfdCtrZoneTitle(object item)
        {
            if (item is fdCtrZone)
            {
                fdCtrZone z = item as fdCtrZone;
                z.lbl_Value1.DoubleClick += Z_Click;
                //z.Click += Z_Click;
                _monitorzone[z] = NetLine.zone.Find(v => v.ID == z.ZoneID);
                if (_monitorzone[z] == null) return;
                //z.Text = _monitorzone[z].ZoneName[MultipleLanguage.systemLanguageIndex];
                //z.Unit = _monitorzone[z].Unit;
                if (z.V1ID == 0) z.lbl_Value1.Visible = false;
                if (z.V2ID == 0) z.lbl_Value2.Visible = false;
                z.BackColor = z.lbl_Value2.BackColor;
                MultipleLanguage.formLanguage[this.Name].Add(
                    MultipleLanguage.getLanguageCtrl(z.Name, "fdCtrZone", "Text", _monitorzone[z].ZoneName, "", "Arial, 9pt")
                    );
            }
        }


        private void Z_Click(object sender, EventArgs e)
        {
            isShowOverPV = !isShowOverPV;
        }

        /// <summary>
        /// 点击显示各个工位的信息
        /// </summary>
        private void LblBox_Click(object sender, EventArgs e)//用来展示数据
        {
            Label lbl = sender as Label;
            if (lbl.Tag == null) return;
            ProcessBox pb = NetLine.pBox[Convert.ToInt32(lbl.Tag)];
            netForms.fmPbox = new Form_ProcessBox(pb);
            netForms.fmPbox.ShowDialog();
            netForms.fmPbox = null;
        }
        /// <summary>
        /// 小车移动函数，使用线程
        /// </summary>
        /// <param name="car">界面上小车的panel实例</param>
        /// <param name="top_from">移动时的开始位置</param>
        /// <param name="top_to">移动时的结束位置</param>
        /// <param name="movingtime">移动所需要的时间</param>
        private void ShowCarMoving(Control car, int top_from, int top_to, float movingtime)
        {
            float step = (top_to - top_from) / movingtime;
            Task.Run(() =>
            {
                Stopwatch sp = new Stopwatch();
                sp.Start();
                while (sp.ElapsedMilliseconds <= movingtime)
                {
                    float v = top_from + step * sp.ElapsedMilliseconds;
                    this.Invoke((EventHandler)delegate
                    {
                        car.Top = (int)v;
                        if (top_from < top_to && car.Top >= top_to) car.Top = top_to;
                        if (top_from > top_to && car.Top <= top_to) car.Top = top_to;
                    });
                    Thread.Sleep(50);
                    Application.DoEvents();
                }
                sp.Stop();
            });
        }
        //显示各个工位的状态
        private void ShowBoxStatus()
        {
            try
            {
                this.Invoke((EventHandler)delegate
                {
                    for (int i = 0; i < lblBox.Count && i < NetLine.pBox.Count; i++)
                    {
                        try
                        {
                            if (NetLine.pBox[i].LoadIndex == 0)//无料的情况
                            {
                                lblBox[i].BackColor = this.BackColor;
                                lblBox[i].ForeColor = Color.Silver;
                                lblBox[i].Text = (i + 1).ToString();
                            }
                            else//有料的时候显示不同的颜色
                            {
                                lblBox[i].Text = NetLine.pBox[i].BoxSerial.ToString();
                                lblBox[i].BackColor = fdPublicFunction.boxColorSet[NetLine.pBox[i].LampCode].backColor;
                                lblBox[i].ForeColor = fdPublicFunction.boxColorSet[NetLine.pBox[i].LampCode].foreColor;
                            }
                        }
                        catch (Exception)
                        {
                            continue;
                        }
                    }
                });
            }
            catch (Exception)
            {
            }
           
        }
        /// <summary>
        /// 设置界面内各个分区显示内容当前值和实际值和报警的显示
        /// </summary>
        public void SetZoneData()
        {
            foreach (fdCtrZone fdz in _monitorzone.Keys)
            {
                if (_monitorzone[fdz] != null)
                {
                    StringBuilder v1 = new StringBuilder();
                    StringBuilder v2 = new StringBuilder();
                    if (_monitorzone[fdz].pv != null)
                    {
                        v1.Append(_monitorzone[fdz].pv.VisibleValue);//加入当前只
                        if (isShowOverPV && _monitorzone[fdz].ovpv != null)//判断是否需要显示过热值，并且有过热值
                        {
                            v1.Append("/").Append(_monitorzone[fdz].ovpv.VisibleValue);//添加显示过热值的显示
                        }
                        if (_monitorzone[fdz].pv.DataType.ToUpper() == "TIME")
                            v1.Replace('.', ':');
                    }
                    if (_monitorzone[fdz].sv != null)
                    {
                        v2.Append(_monitorzone[fdz].sv.VisibleValue);
                        if (_monitorzone[fdz].sv.DataType.ToUpper() == "TIME")
                            v2.Replace('.', ':');
                    }
                    fdz.SetValues(v1.ToString(), v2.ToString());

                    //对没有显示区域绑定的zone进行报警内容的判断，显示显示组的报警状态
                    if (_monitorzone[fdz].BindAlarmID.Count > 0)
                    {
                        bool isAlarm = false;
                        for (int j = 0; j < _monitorzone[fdz].BindAlarmID.Count; j++)
                        {
                            Alarm al = NetLine.alarm.Find(x => x.AlarmID == _monitorzone[fdz].BindAlarmID[j]);
                            if (al != null)
                                isAlarm = isAlarm | al.AlarmValue;
                        }
                        fdz.IsZoneAlarm = isAlarm;
                    }
                }
            }
        }
        private void Form_Monitor_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(_tim.Enabled) _tim.Stop();
            if(_timfan.Enabled) _timfan.Stop();
        }


        private void ReLoadZoneTitle()
        {
            foreach (fdCtrZone fdz in _monitorzone.Keys)
            {
                if (_monitorzone[fdz] != null) fdz.Text = _monitorzone[fdz].ZoneName[formLanguageIndex];
            }
        }
        private void Form_Monitor_Activated(object sender, EventArgs e)
        {
            if (formLanguageIndex != MultipleLanguage.systemLanguageIndex)
            {
                formLanguageIndex = MultipleLanguage.systemLanguageIndex;
                //ReLoadZoneTitle();
            }
        }
    }

    class ControlPos
    {
        public Control ctl { get; set; }
        public int upside { get; set; }
        public int downside { get; set; }
    }

}

